<?php

// +----------------------------------------------------------------------
// | URL解析、路由和调度
// +----------------------------------------------------------------------
//支持的URL模式
define('URL_COMMON', 0);   //普通模式
define('URL_PATHINFO', 1);   //PATHINFO模式
define('URL_REWRITE', 2);   //REWRITE模式

class dispatcher extends fee {

	//URL映射到控制器
	static public function dispatch() {
		$urlMode = C('URL_MODEL');
		if ($urlMode == URL_REWRITE) {
			//当前项目地址
			$url = dirname(_PHP_FILE_);
			if ($url == '/' || $url == '\\')
				$url = '';
			define('PHP_FILE', $url);
		}else {
			//当前项目地址
			define('PHP_FILE', _PHP_FILE_);
		}

		self::getPathInfo();
		$rule = $params = array();
		$regx = trim($_SERVER['PATH_INFO'], '/');
		$depr = C('URL_PATHINFO_DEPR');

		//有phpinfo路径 或者 开启了子域名 则进行路由参数配置
		if ($regx || C('URL_SUB_DOMAIN_ON')) {
			if (C('URL_HTML_SUFFIX'))
				$_SERVER['PATH_INFO'] = preg_replace('/\.' . C('URL_HTML_SUFFIX') . '$/', '', $_SERVER['PATH_INFO']);
			$params = explode($depr, $regx); //url参数
			
			$subDomain = '';
			if (C('URL_SUB_DOMAIN_ON')) {
				C('URL_ROUTER_ON', true); //开启子域名自动开启路由开关
				$subDomain = strtolower(substr($_SERVER['HTTP_HOST'], 0, strpos($_SERVER['HTTP_HOST'], '.')));
				define('SUB_DOMAIN', $subDomain);
				$rule = C('URL_SUB_DOMAIN_RULES');
			} elseif (C('URL_ROUTER_ON')) {
				$rule = C('URL_ROUTE_RULES');
			}

			//处理路由规则
			if (empty($rule) || !self::routerCheck($rule, $params)) {
				//没有路由 按url默认规则分配参数
				$app_list = C('APP_GROUP_LIST');
				$app_list[] = C('DEFAULT_GROUP');
				if (isset($params[0]) && in_array($params[0], $app_list)) {
					$var[C('VAR_GROUP')] = array_shift($params);
				} else {
					$var[C('VAR_GROUP')] = C('DEFAULT_GROUP');
				}
				if (isset($params[0]))
					$var[C('VAR_MODULE')] = array_shift($params);
				if (isset($params[0]))
					$var[C('VAR_ACTION')] = array_shift($params);
				// 解析剩余的URL参数
				$res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', implode('/', $params));
				$_GET = array_merge($var, $_GET);
			}
		}

		// 获取分组 模块和操作名称
		define('GROUP_NAME', self::getGroup(C('VAR_GROUP')));
		define('MODULE_NAME', self::getModule(C('VAR_MODULE')));
		define('ACTION_NAME', self::getAction(C('VAR_ACTION')));

		// URL常量
		// 当前页面地址
		define('__SELF__', $_SERVER['REQUEST_URI']);
		define('__INFO__', $_SERVER['PATH_INFO']);

		// 当前项目地址		
		define('__APP__', get_host() . PHP_FILE);
		define('__URL__', __APP__);
		//当前分组url地址
		define('__GROUP__', ( $subDomain || GROUP_NAME == DEFAULT_GROUP ) ? __APP__ : __APP__ . '/' . GROUP_NAME);
		//当前模块地址
		define('__MODULE__', __GROUP__ . $depr . MODULE_NAME);
		// 当前操作地址
		define('__ACTION__', __MODULE__ . $depr . ACTION_NAME);

		//保证$_REQUEST正常取值
		$_REQUEST = array_merge($_POST, $_GET);
	}

	//路由检测
	static public function routerCheck($routers, $params) {
		$params2 = $params;
		$router_name = defined('SUB_DOMAIN') ? SUB_DOMAIN : array_shift($params);

		// 简单路由定义：array('分组','模块','操作名','var1,var2'),
		if (isset($routers[$router_name]) && !empty($routers[$router_name])) {
			$rule = $routers[$router_name];
			$var[C('VAR_GROUP')] = !empty($rule[0]) ? $rule[0] : array_shift($params);
			$var[C('VAR_MODULE')] = !empty($rule[1]) ? $rule[1] : array_shift($params);
			$var[C('VAR_ACTION')] = !empty($rule[2]) ? $rule[2] : array_shift($params);

			// 处理路由规则的路由参数
			$vars = $rule[3];
			if ($vars) {
				$vars = explode(',', $vars);
				for ($i = 0; $i < count($vars); $i++) {
					$tmp = array_shift($params);
					if ($tmp !== null)
						$var[$vars[$i]] = $tmp;
				}
			}

			// 解析剩余的URL参数
			$res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', implode('/', $params));
			$_GET = array_merge($var, $_GET);
			return true;
		}elseif (isset($routers[$router_name . '*']) && !empty($routers[$router_name . '*'])) {
			// 正则路由定义
			$router = $routers[$router_name . '*'];
			$depr = C('URL_PATHINFO_DEPR');
			foreach ($router as $key => $rule) {
				if (preg_match($rule[4], implode($depr, $params), $matches)) {
					$var[C('VAR_GROUP')] = !empty($rule[0]) ? $rule[0] : array_shift($params);
					$var[C('VAR_MODULE')] = !empty($rule[1]) ? $rule[1] : array_shift($params);
					$var[C('VAR_ACTION')] = !empty($rule[2]) ? $rule[2] : array_shift($params);

					// 处理路由规则的路由参数
					$vars = $rule[3];
					if ($vars) {
						$vars = explode(',', $vars);
						for ($i = 0; $i < count($vars); $i++)
							$var[$vars[$i]] = array_shift($params);
					}

					// 解析剩余的URL参数
					$res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', implode('/', $params));
					$_GET = array_merge($var, $_GET);
					return true;
				}
			}
		}
		return false;
	}

	//获得服务器的PATH_INFO信息
	public static function getPathInfo() {
		if (!empty($_GET[C('VAR_PATHINFO')])) {
			// 兼容PATHINFO 参数
			$path = $_GET[C('VAR_PATHINFO')];
			unset($_GET[C('VAR_PATHINFO')]);
		} elseif (!empty($_SERVER['PATH_INFO'])) {
			$pathInfo = $_SERVER['PATH_INFO'];
			if (0 === strpos($pathInfo, $_SERVER['SCRIPT_NAME']))
				$path = substr($pathInfo, strlen($_SERVER['SCRIPT_NAME']));
			else
				$path = $pathInfo;
		}elseif (!empty($_SERVER['ORIG_PATH_INFO'])) {
			$pathInfo = $_SERVER['ORIG_PATH_INFO'];
			if (0 === strpos($pathInfo, $_SERVER['SCRIPT_NAME']))
				$path = substr($pathInfo, strlen($_SERVER['SCRIPT_NAME']));
			else
				$path = $pathInfo;
		}elseif (!empty($_SERVER['REDIRECT_PATH_INFO'])) {
			$path = $_SERVER['REDIRECT_PATH_INFO'];
		} elseif (!empty($_SERVER["REDIRECT_Url"])) {
			$path = $_SERVER["REDIRECT_Url"];
			if (empty($_SERVER['QUERY_STRING']) || $_SERVER['QUERY_STRING'] == $_SERVER["REDIRECT_QUERY_STRING"]) {
				$parsedUrl = parse_url($_SERVER["REQUEST_URI"]);
				if (!empty($parsedUrl['query'])) {
					$_SERVER['QUERY_STRING'] = $parsedUrl['query'];
					parse_str($parsedUrl['query'], $GET);
					$_GET = array_merge($_GET, $GET);
					reset($_GET);
				} else {
					unset($_SERVER['QUERY_STRING']);
				}
				reset($_SERVER);
			}
		}
		if (C('URL_HTML_SUFFIX') && !empty($path)) {
			$suffix = substr(C('URL_HTML_SUFFIX'), 1);
			$path = preg_replace('/\.' . $suffix . '$/', '', $path);
		}
		$_SERVER['PATH_INFO'] = empty($path) ? '/' : $path;
	}

	//获得实际的模块名称
	static public function getModule($var='') {
		$var = $var ? $var : C('VAR_MODULE');
		$module = !empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_MODULE');
		unset($_GET[$var]);
		return strtolower($module);
	}

	//获得实际的操作名称
	static public function getAction($var='') {
		$var = $var ? $var : C('VAR_ACTION');
		$action = !empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_ACTION');
		unset($_GET[$var]);
		return strtolower($action);
	}

	//获得实际的分组名称
	static public function getGroup($var='') {
		$var = $var ? $var : C('VAR_GROUP');
		$group = !empty($_GET[$var]) ? $_GET[$var] : DEFAULT_GROUP;
		unset($_GET[$var]);
		return strtolower($group);
	}

}

?>